package com.betterjr.modules.application.service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.betterjr.common.service.BaseService;
import com.betterjr.common.utils.BTAssert;
import com.betterjr.common.utils.Collections3;
import com.betterjr.common.utils.QueryTermBuilder;
import com.betterjr.common.utils.UserUtils;
import com.betterjr.modules.application.IApplicationUndercarriage;
import com.betterjr.modules.application.dao.ApplicaitonCustRoleMapper;
import com.betterjr.modules.application.data.AmsMenuResourceRelationConstantCollections;
import com.betterjr.modules.application.data.ApplicationConstantCollections;
import com.betterjr.modules.application.data.ApplicationCustRoleConstantCollections;
import com.betterjr.modules.application.data.ApplicationGroupConstantCollections;
import com.betterjr.modules.application.data.ApplicationOperatorConstantCollections;
import com.betterjr.modules.application.data.ApplicationOperorgConstantCollections;
import com.betterjr.modules.application.entity.ApplicaitonCustRole;
import com.betterjr.modules.application.entity.Application;
import com.betterjr.modules.application.entity.ApplicationOperator;
import com.betterjr.modules.customer.entity.CustMechBase;
import com.betterjr.modules.customer.service.CustMechBaseService;
import com.betterjr.modules.operator.service.SysOperatorRoleRelationService;
import com.betterjr.modules.role.entity.Role;
import com.betterjr.modules.role.service.RoleService;
import com.google.common.collect.Lists;

@Service
public class ApplicationCustRoleService extends BaseService<ApplicaitonCustRoleMapper, ApplicaitonCustRole>
        implements IApplicationUndercarriage {

    @Autowired
    private ApplicationService applicationService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private CustMechBaseService custService;

    @Autowired
    private SysOperatorRoleRelationService roleRelationService;

    @Autowired
    private ApplicationOperatorService applicationOperatorService;

    /**
     * 
     * @Title: SaveUpdateApplicationCustRole 
     * @Description: 新增修改应用客户角色表信息 
     * @param anCustNo
     * @param anRoleId
     * @param anApplicationIds
     * @return List<ApplicaitonCustRole>
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午3:58:31
     */
    public List<ApplicaitonCustRole> saveUpdateApplicationCustRole(Long anCustNo, Long anRoleId,
            String anApplicationIds) {

        List<ApplicaitonCustRole> custRoleList = queryEffectiveApplicationCustRole(anCustNo, anRoleId);
        if (Collections3.isEmpty(custRoleList)) {
            // 新增信息
            return saveAddApplicationCustRole(anCustNo, anRoleId, anApplicationIds);
        }

        // 需要修改信息
        StringBuilder sb = new StringBuilder();
        for (ApplicaitonCustRole applicaitonCustRole : custRoleList) {
            sb.append(applicaitonCustRole.getApplicationId());
        }
        // 得到插入的id列表
        String okApplicationIds = findDifferencesResources(anApplicationIds, sb.toString(),
                AmsMenuResourceRelationConstantCollections.AMSMENURESOURCERELATION_BUSINSTATUS_EFFECTIVE);
        // 插入新增加的应用
        List<ApplicaitonCustRole> list = saveAddApplicationCustRole(anCustNo, anRoleId, okApplicationIds);
        // 得到需要过期的id列表
        String errorApplicationIds = findDifferencesResources(anApplicationIds, sb.toString(),
                AmsMenuResourceRelationConstantCollections.AMSMENURESOURCERELATION_BUSINSTATUS_NOEFFECTIVE);
        saveUpdateApplicationCustRoleToNoEffective(anCustNo, anRoleId, errorApplicationIds);
        return list;

    }

    /**
     * 
     * @Title: queryApplicationCustRole 
     * @Description: 根据客户号和角色id查询所有的生效的应用信息
     * @param anCustNo
     * @param anRoleId
     * @return List<ApplicaitonCustRole>
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午4:06:04
     */
    @SuppressWarnings("unchecked")
    public List<ApplicaitonCustRole> queryEffectiveApplicationCustRole(Long anCustNo, Long anRoleId) {

        BTAssert.notNull(anCustNo, "数据为空,操作失败");
        BTAssert.notNull(anRoleId, "数据为空,操作失败");
        Map<String, Object> map = QueryTermBuilder.newInstance().put("custNo", anCustNo).put("roleId", anRoleId)
                .put("businStatus", ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_EFFECTIVE)
                .build();

        return this.selectByProperty(map);

    }

    /**
     * 
     * @Title: saveUpdateApplicationCustRoleToNoEffective 
     * @Description: 删除应用
     * @param anCustNo
     * @param anRoleId
     * @param errorApplicationIds applicaitonids 应用集合
     * @return List<ApplicaitonCustRole>
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午5:04:57
     */
    private List<ApplicaitonCustRole> saveUpdateApplicationCustRoleToNoEffective(Long anCustNo, Long anRoleId,
            String errorApplicationIds) {

        if (StringUtils.isNoneBlank(errorApplicationIds)) {

            List<String> list = Arrays
                    .asList(errorApplicationIds.split(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR));
            if (!Collections3.isEmpty(list)) {
                List<Long> longList = new ArrayList<>(list.size());
                for (String str : list) {
                    try {
                        longList.add(Long.parseLong(str));
                    }
                    catch (Exception e) {

                    }
                }

                if (!Collections3.isEmpty(longList)) {
                    List<ApplicaitonCustRole> applicationCustRoleList = this.queryApplicationCustRole(anCustNo,
                            anRoleId, longList);
                    for (ApplicaitonCustRole applicaitonCustRole : applicationCustRoleList) {
                        applicaitonCustRole.setBusinStatus(
                                ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_DELETED);
                        this.updateByPrimaryKeySelective(applicaitonCustRole);
                    }

                    return applicationCustRoleList;
                }

            }
        }

        return null;

    }

    /**
     * 
     * @Title: queryApplicationCustRole 
     * @Description: 查询某个企业下的某个角色中的部分应用企业角色表信息
     * @param anCustNo
     * @param anRoleId
     * @param anApplicaitonIds
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月21日 下午2:15:07
     */
    @SuppressWarnings("unchecked")
    public List<ApplicaitonCustRole> queryApplicationCustRole(Long anCustNo, Long anRoleId,
            List<Long> anApplicaitonIds) {

        BTAssert.notNull(anCustNo, "数据为空,操作失败");
        BTAssert.notNull(anRoleId, "数据为空,操作失败");
        BTAssert.notNull(anApplicaitonIds, "数据为空,操作失败");
        Map<String, Object> map = QueryTermBuilder.newInstance().put("custNo", anCustNo).put("roleId", anRoleId)
                .put("applicationId", anApplicaitonIds).build();

        return this.selectByProperty(map);

    }

    /**
     * 
     * @Title: queryApplicationCustRoleCurrentUser 
     * @Description: 查询当前用户的所有应用企业角色表信息 
     * @param anApplicationTypeId
     * @param anApplicationGroupId
     * @param anBusinStatus 状态 1未生效 2已生效 9已失效
     * @return 
     * @throws 
     * @author xuyp
     * @date 2017年11月21日 下午2:44:16
     */
    @SuppressWarnings("unchecked")
    public List<ApplicaitonCustRole> queryApplicationCustRoleCurrentUser(Long anApplicationTypeId,
            Long anApplicationGroupId, String anBusinStatus) {
        List<Role> roleList = roleRelationService.findRoleByOperId(UserUtils.getOperatorInfo().getId());
        if (Collections3.isEmpty(roleList)) {
            return Lists.newArrayList();
        }
        List<Long> longList = new ArrayList<>(roleList.size());
        for (Role role : roleList) {
            longList.add(role.getId());
        }
        Map<String, Object> build = QueryTermBuilder.newInstance()
                .put("operOrg", UserUtils.getOperatorInfo().getOperOrg()).put("roleId", longList).build();
        if (null != anApplicationTypeId) {
            build.put("applicationTypeId", anApplicationTypeId);
        }
        if (null != anApplicationGroupId) {
            build.put("applicationGroupId", anApplicationGroupId);
        }
        if (StringUtils.isBlank(anBusinStatus)) {
            build.put("businStatus", ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_EFFECTIVE);
        } else {
            if (anBusinStatus.contains(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR)) {
                build.put("businStatus",
                        anBusinStatus.split(ApplicationGroupConstantCollections.SYSTEM_VALUE_FILE_SEPARATOR));
            } else {
                build.put("businStatus", anBusinStatus);
            }
        }

        return this.selectByProperty(build);
    }

    /**
     * 
     * @Title: queryApplicationsCurrentUser 
     * @Description: 查询当前用户的所有应用信息 
     * @param anApplicationTypeId
     * @param anApplicationGroupId
     * @param anBusinStatus  状态 1未生效 2已生效 9已失效
     * @return 查询当前用户的所有应用信息 
     * @throws 
     * @author xuyp
     * @date 2017年11月21日 下午3:21:54
     */
    public List<Application> queryApplicationsCurrentUser(Long anApplicationTypeId, Long anApplicationGroupId,
            String anBusinStatus) {

        List<ApplicaitonCustRole> list = queryApplicationCustRoleCurrentUser(anApplicationTypeId, anApplicationGroupId,
                anBusinStatus);
        if (Collections3.isEmpty(list)) {
            return Lists.newArrayList();
        }

        List<Application> applications = new ArrayList<>(list.size());
        for (ApplicaitonCustRole applicationCustRole : list) {
            applications.add(applicationService.selectByPrimaryKey(applicationCustRole.getApplicationId()));
        }

        // 查询当前操作员个性化定制(过滤拦截的应用)
        List<ApplicationOperator> opeatorApplicationList = applicationOperatorService
                .queryApplicationOperatorList(anBusinStatus, UserUtils.getOperatorInfo().getId(), null);
        applications = personalizedApplication(applications, opeatorApplicationList);

        return applications;
    }

    /**
     * 
     * @Title: saveAddApplicationCustRole 
     * @Description: 给企业角色分配应用信息 
     * @param anCustNo
     * @param anRoleId
     * @param anApplicationIds
     * @return List<ApplicaitonCustRole>
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午3:30:03
     */
    private List<ApplicaitonCustRole> saveAddApplicationCustRole(Long anCustNo, Long anRoleId,
            String anApplicationIds) {

        BTAssert.notNull(anCustNo, "数据为空,操作失败");
        BTAssert.notNull(anRoleId, "数据为空,操作失败");
        BTAssert.isTrue(StringUtils.isNotBlank(anApplicationIds), "数据为空,操作失败");
        Role role = roleService.findRoleById(anRoleId);
        CustMechBase base = custService.findCustMechBaseByCustNo(anCustNo);
        List<Application> applicationList = applicationService.queryEffectiveApplicaitonsByIds(anApplicationIds);
        if (Collections3.isEmpty(applicationList)) {
            return new ArrayList<>();
        }

        List<ApplicaitonCustRole> lists = new ArrayList<>(applicationList.size());
        for (Application application : applicationList) {
            // 先将系统中有的置为删除，防止出现多条生效的记录
            saveUpdateToDelete(anCustNo, anRoleId, application.getId());

            ApplicaitonCustRole applicationCustRole = convertApplication(application);
            applicationCustRole.setCustName(base.getCustName());
            applicationCustRole.setCustNo(anCustNo);
            applicationCustRole.setOperOrg(base.getOperOrg());
            applicationCustRole.setRoleId(anRoleId);
            applicationCustRole.setRoleName(role.getRoleName());
            applicationCustRole.saveAddValue();
            this.insertSelective(applicationCustRole);
            lists.add(applicationCustRole);
        }

        return lists;
    }

    /**
     * 
     * @Title: saveUpdateToDelete 
     * @Description: 将指定的应用信息设置成删除状态 
     * @param anCustNo
     * @param anRoleId
     * @param anApplicationId
     * @return TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午4:58:17
     */
    @SuppressWarnings("unchecked")
    private List<ApplicaitonCustRole> saveUpdateToDelete(Long anCustNo, Long anRoleId, Long anApplicationId) {

        Map<String, Object> map = QueryTermBuilder.newInstance().put("custNo", anCustNo).put("roleId", anRoleId)
                .put("applicationId", anApplicationId)
                .put("businStatus",
                        new String[] { ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_EFFECTIVE,
                                ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_NOEFFECTIVE })
                .build();

        List<ApplicaitonCustRole> list = this.selectByProperty(map);
        for (ApplicaitonCustRole applicaitonCustRole : list) {
            applicaitonCustRole
                    .setBusinStatus(ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_DELETED);
            this.updateByPrimaryKeySelective(applicaitonCustRole);
        }
        return list;

    }

    /**
     * 应用下载 同步下载角色中的应用
     * <p>Overriding Method of saveUndercarriageApplication</p>  
     * <p>Description: </p> 
     * @param anApplicationId 
     * @see com.betterjr.modules.application.IApplicationUndercarriage#saveUndercarriageApplication(java.lang.Long) 
     * @author xuyp
     * @date 2017年11月20日 下午3:54:23
     */
    @Override
    public void saveUndercarriageApplication(Long anApplicationId) {
        if (null != anApplicationId) {
            Application application = applicationService.selectByPrimaryKey(anApplicationId);
            if (null != application) {
                saveUndercarriageApplicationCustRole(anApplicationId);
            }
        }

    }

    /**
     * 
     * @Title: saveUndercarriageApplicationCustRole 
     * @Description: 批量下架应用 
     * @param anApplicationId TODO(说明)
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午3:50:26
     */
    @SuppressWarnings("unchecked")
    private List<ApplicaitonCustRole> saveUndercarriageApplicationCustRole(Long anApplicationId) {

        Map<String, Object> map = QueryTermBuilder.newInstance().put("applicationId", anApplicationId)
                .put("businStatus",
                        new String[] { ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_EFFECTIVE,
                                ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_NOEFFECTIVE })
                .build();
        List<ApplicaitonCustRole> list = this.selectByProperty(map);
        for (ApplicaitonCustRole applicationCustRole : list) {
            applicationCustRole
                    .setBusinStatus(ApplicationOperorgConstantCollections.APPLICATIONOPERORG_BUSINSTATUS_DELETED);
            this.updateByPrimaryKeySelective(applicationCustRole);
        }

        return list;
    }

    /**
     * 
     * @Title: convertApplication 
     * @Description: 将应用中的信息封装到应用企业角色表中
     * @param application
     * @return ApplicaitonCustRole 应用企业角色表
     * @throws 
     * @author xuyp
     * @date 2017年11月20日 下午3:29:10
     */
    private ApplicaitonCustRole convertApplication(Application application) {
        ApplicaitonCustRole applicaitonCustRole = new ApplicaitonCustRole();
        applicaitonCustRole.setApplicationGroupId(application.getApplicationGroupId());
        applicaitonCustRole.setApplicationId(application.getId());
        applicaitonCustRole.setApplicationTypeId(application.getApplicationTypeId());
        return applicaitonCustRole;
    }

    /**
     * 
     * @Title: findDifferencesResources 
     * @Description: 查找两个字符串不同的信息 
     * @param anRourceIds  新资源集合
     * @param anOldResourceIds  旧资源集合
     * @param flag 1：返回以新资源为标准的多出来的资源    9 返回以旧资源为标准的多余的资源
     * @return 
     * @throws 
     * @author xuyp
     * @date 2017年11月21日 上午9:51:48
     */
    private String findDifferencesResources(String anRourceIds, String anOldResourceIds, String flag) {

        StringBuilder okSb = new StringBuilder();
        StringBuilder errorSb = new StringBuilder();
        if (StringUtils.isBlank(anRourceIds)) {
            if (AmsMenuResourceRelationConstantCollections.AMSMENURESOURCERELATION_BUSINSTATUS_EFFECTIVE.equals(flag)) {
                return okSb.toString();
            } else {
                return anOldResourceIds;
            }
        }

        List<String> resourceIds = Arrays.asList(anRourceIds.split(","));
        List<String> oldResourceIds = Arrays.asList(anOldResourceIds.split(","));
        for (String resourceId : resourceIds) {
            if (!oldResourceIds.contains(resourceId)) {
                okSb.append(resourceId).append(",");
            }
        }

        for (String oldResourceId : oldResourceIds) {
            if (!resourceIds.contains(oldResourceId)) {
                errorSb.append(oldResourceId).append(",");
            }
        }

        if (AmsMenuResourceRelationConstantCollections.AMSMENURESOURCERELATION_BUSINSTATUS_EFFECTIVE.equals(flag)) {
            return okSb.toString();
        } else {
            return errorSb.toString();
        }

    }

    /**
     * 
     * @Title: personalizedApplication 
     * @Description: 个性化定制应用（去除拦截的应用） 
     * @param applications
     * @param opeatorApplicationList
     * @return 
     * @throws 
     * @author xuyp
     * @date 2017年11月30日 上午10:03:11
     */
    private List<Application> personalizedApplication(List<Application> applications,
            List<ApplicationOperator> opeatorApplicationList) {

        if (Collections3.isEmpty(opeatorApplicationList) || Collections3.isEmpty(applications)) {
            return applications;
        }
        for (ApplicationOperator applicationOperator : opeatorApplicationList) {

            // 拦截的条件判断 必须是生效的个性化 和 个性化数据中是拦截状态
            boolean filterFlag = applicationOperator != null
                    && applicationOperator.getBusinStatus()
                            .equals(ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_EFFECTIVE)
                    && applicationOperator.getFilterFalg()
                            .equals(ApplicationOperatorConstantCollections.APPLICATIONOPERATOR_FILTERFLAG_YES);
            if (filterFlag) {
                Application application = applicationService.selectByPrimaryKey(applicationOperator.getApplicationId());
                if (application != null) {
                    if (application.getBusinStatus()
                            .equals(ApplicationConstantCollections.APPLICATION_BUSINSTATUS_PUBLISHING)) {
                        applications.remove(application);
                    } else {
                        applicationOperator.setBusinStatus(
                                ApplicationCustRoleConstantCollections.APPLICATIONCUSTROLE_BUSINSTATUS_DELETED);
                        applicationOperatorService.updateByPrimaryKeySelective(applicationOperator);
                    }
                }
            }
        }

        return applications;
    }

}
